#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <unistd.h>   // 提供fork、close、write、read等系统调用
#include <sys/wait.h> // 提供waitpid函数
using namespace std;

int main()
{
    // 1. 创建管道，pipefd[0]是读端口，pipefd[1]是写端口
    int pipefd[2];
    if (pipe(pipefd) == -1)
    {
        cerr << "Failed to create pipe." << endl;
        return 1;
    }

    // 2. 创建子进程
    pid_t child_pid = fork();
    if (child_pid == -1)
    {
        cerr << "Failed to fork." << endl;
        return 1;
    }

    if (child_pid == 0)
    {
        // 子进程部分（读端）
        // 3.1 子进程关闭不需要的管道写端
        close(pipefd[1]);

        // 缓冲区，用于接收父进程发送的消息
        char buffer[1024];

        // 循环读取管道中的数据，直到读到文件结束符（表示父进程已关闭写端口）
        while (true)
        {
            // 从管道读取数据，返回读取的字节数，如果没有数据则阻塞等待
            ssize_t bytes_read = read(pipefd[0], buffer, sizeof(buffer) - 1);

            if (bytes_read > 0)
            {
                // 将读取的数据转为C风格字符串
                buffer[bytes_read] = '\0';

                // 输出接收到的消息
                cout << "Child [" << getpid() << "] received a message: " << buffer << endl;
            }
            else if (bytes_read == 0) // 读取到文件结束，父进程已关闭写端
            {
                cout << "Writer quit (Father), Child quitting too" << endl;
                break;
            }
            else if (bytes_read == -1)
            {
                cerr << "Error reading from pipe." << endl;
                return 1;
            }
        }

        // 子进程完成读取后关闭读端
        close(pipefd[0]);

        // 子进程完成任务后退出
        exit(0);
    }
    else
    {
        // 父进程部分（写端）
        // 3.1 父进程关闭不需要的管道读端
        close(pipefd[0]);

        // 初始化一条要发送的消息
        string message = "hello, I'm father process";
        int count = 0;
        char send_buffer[1024];

        // 循环向管道写入消息，直到达到指定次数
        while (true)
        {
            // 构造要发送的消息内容
            snprintf(send_buffer, sizeof(send_buffer), "%s[%d] : %d", message.c_str(), getpid(), count++);

            // 向管道写入数据
            ssize_t bytes_written = write(pipefd[1], send_buffer, strlen(send_buffer));

            if (bytes_written == -1)
            {
                cerr << "Error writing to pipe." << endl;
                return 1;
            }

            // 模拟延时，每次发送消息后等待1秒
            sleep(1);

            if (count == 5) // 发送指定数量的消息后退出循环
            {
                cout << "Writer quit (Father)" << endl;
                break;
            }
        }

        // 发送完毕所有消息后，关闭写端
        close(pipefd[1]);

        // 4. 父进程等待子进程结束，并获取其退出状态
        pid_t result = waitpid(child_pid, nullptr, 0); // 等待子进程结束
        if (result == -1)
        {
            cerr << "Error in waitpid." << endl;
            return 1;
        }
        cout << "Child PID: " << child_pid << ", Return Value from waitpid: " << result << endl;
    }

    return 0;
}